#include <glib.h>
#include <SDL.h>
#include "racanhack.h"
#include "task.h"
#include "video.h"
#include "cave.h"
#include "player.h"
#include "monster.h"
#include "object.h"
#include "stair.h"
#include "floor.h"

gboolean is_map_pass(struct _coord coord)
{
  return curf->cave.map[coord.x][coord.y].pass;
}

gboolean is_map_wall(struct _coord coord)
{
  return !(curf->cave.map[coord.x][coord.y].pass);
}

gboolean is_map_waynavi(struct _coord coord)
{
  return curf->cave.map[coord.x][coord.y].waynavi;
}

gboolean is_map_passed(struct _coord coord)
{
  return curf->cave.map[coord.x][coord.y].passed;
}

gboolean is_map_disturb(struct _coord coord)
{
  return curf->cave.map[coord.x][coord.y].disturb;
}

struct _room *at_room(struct _coord coord)
{
  return curf->cave.map[coord.x][coord.y].room;
}

struct _coord rand_coord()
{
  struct _room *room;
  struct _coord coord;
  int i;
  i = g_random_int_range(0, g_list_length(curf->cave.room_list));
  room = g_list_nth_data(curf->cave.room_list, i);
  coord.x = g_random_int_range(room->lx, room->hx + 1);
  coord.y = g_random_int_range(room->ly, room->hy + 1);
  if (is_object(coord) || is_stair(coord) || is_monster(coord)) {
    return rand_coord();
  };
  return coord;
}

void floor_init()
{
  floor_list = NULL;
}

void floor_free()
{
  GList *li;
  struct _floor *floor;
  for (li = g_list_first(floor_list); li != NULL; li = g_list_next(li)) {
    floor = (struct _floor *)li->data;
    cave_free(&floor->cave);
    g_list_foreach(floor->monster_list, (GFunc)my_free, NULL);
    g_list_free(floor->monster_list);
    g_list_foreach(floor->object_list, (GFunc)my_free, NULL);
    g_list_free(floor->object_list);
    g_list_foreach(floor->stair_list, (GFunc)my_free, NULL);
    g_list_free(floor->stair_list);
  };
  g_list_foreach(floor_list, (GFunc)my_free, NULL);
  g_list_free(floor_list);
}

struct _floor *floor_add()
{
  struct _floor *floor;
  floor = my_new(struct _floor, 1);
  cave_generate(&floor->cave);
  floor->monster_list = NULL;
  floor->object_list = NULL;
  floor->stair_list = NULL;
  floor_list = g_list_append(floor_list, floor);
  return(floor);
}

struct _floor *floor_tutorial_add()
{
  struct _floor *floor;
  floor = my_new(struct _floor, 1);
  cave_generate_tutorial(&floor->cave);
  floor->monster_list = NULL;
  floor->object_list = NULL;
  floor->stair_list = NULL;
  floor_list = g_list_append(floor_list, floor);
  return(floor);
}

void floor_curf_set(struct _floor *floor)
{
  curf = floor;
};

void floor_curf_store() 
{
  GList *li;
  struct _monster *monster;
  struct _object *object;
  struct _stair *stair;
  for (li = g_list_first(curf->monster_list); li != NULL; li = g_list_next(li)) {
    monster = (struct _monster *)li->data;
    monster->sprite->alive = FALSE;
    monster->sprite = NULL;
    monster->task->alive = FALSE;
    monster->task = NULL;
  };
  for (li = g_list_first(curf->object_list); li != NULL; li = g_list_next(li)) {
    object = (struct _object *)li->data;
    object->sprite->alive = FALSE;
    object->sprite = NULL;
    object->task->alive = FALSE;
    object->task = NULL;
  };
  for (li = g_list_first(curf->stair_list); li != NULL; li = g_list_next(li)) {
    stair = (struct _stair *)li->data;
    stair->sprite->alive = FALSE;
    stair->sprite = NULL;
    stair->task->alive = FALSE;
    stair->task = NULL;
  };
}

void floor_curf_restore() 
{
  GList *li;
  struct _monster *monster;
  struct _object *object;
  struct _stair *stair;
  for (li = g_list_first(curf->monster_list); li != NULL; li = g_list_next(li)) {
    monster = (struct _monster *)li->data;
    monster->sprite = video_sprite_add(Z_ORDER_MONSTER);
    monster->sprite->x = monster->coord.x * SPRITE_W;
    monster->sprite->y = monster->coord.y * SPRITE_H;
    monster_trans_state(monster_turn_end, monster);
  };
  for (li = g_list_first(curf->object_list); li != NULL; li = g_list_next(li)) {
    object = (struct _object *)li->data;
    object->sprite = video_sprite_add(Z_ORDER_OBJECT);
    object->sprite->x = SPRITE_W * object->coord.x;
    object->sprite->y = SPRITE_H * object->coord.y;
    object_trans_state(object_on_floor, object);
  };
  for (li = g_list_first(curf->stair_list); li != NULL; li = g_list_next(li)) {
    stair = (struct _stair *)li->data;
    stair->sprite = video_sprite_add(Z_ORDER_STAIR);
    stair->sprite->x = stair->coord.x * SPRITE_W;
    stair->sprite->y = stair->coord.y * SPRITE_H;
    stair_trans_state(stair_idle, stair);
  };
}
